{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "945a0864",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import yfinance as yf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "771ec0f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Download S&P 500 front month futures data\n",
    "prices = yf.download('ES=F')['Adj Close']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2d6782c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate daily logarithmic returns\n",
    "log_returns = np.log(prices).diff()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a1184cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Annualize returns and volatility\n",
    "annualized_return = log_returns.mean() * 252\n",
    "annualized_vol = log_returns.std() * np.sqrt(252)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7f89e1a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Download the 3-month Treasury bill rate as the risk-free rate\n",
    "sp500_start_date = str(prices.index[0])[:10]\n",
    "risk_free_rates = yf.download('^IRX', start=sp500_start_date)['Adj Close']\n",
    "avg_risk_free_rate = risk_free_rates.mean() / 100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44f479c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate the Sharpe Ratio\n",
    "sharpe_ratio = (annualized_return - avg_risk_free_rate) / annualized_vol\n",
    "# Calculate the Sortino Ratio\n",
    "downside_vol = log_returns[log_returns<0].std() * np.sqrt(252)\n",
    "sortino_ratio = (annualized_return - avg_risk_free_rate) / downside_vol\n",
    "# Calculate the Calmar Ratio\n",
    "cum_returns = np.exp(log_returns.cumsum())\n",
    "drawdowns = (cum_returns.cummax() - cum_returns) / cum_returns.cummax()\n",
    "max_drawdown = np.max(drawdowns)\n",
    "calmar_ratio = annualized_return / max_drawdown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf8c07ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "print()\n",
    "print(f\"annualized_return: {np.round(annualized_return * 100, 1)}%\")\n",
    "print(f\"avg_risk_free_rate: {np.round(avg_risk_free_rate * 100, 1)}%\")\n",
    "print(f\"annualized_volatility: {np.round(annualized_vol * 100, 1)}%\")\n",
    "print(f\"downside_volatility: {np.round(downside_vol * 100, 1)}%\")\n",
    "print(f\"max_drawdown: {np.round(max_drawdown * 100, 1)}%\")\n",
    "print()\n",
    "print(f\"sharpe_ratio: {np.round(sharpe_ratio, 2)}\")\n",
    "print(f\"sortino_ratio: {np.round(sortino_ratio, 2)}\")\n",
    "print(f\"calmar_ratio: {np.round(calmar_ratio, 2)}\")\n",
    "print()"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
